package com.bto.solar.work.config;

import com.alibaba.fastjson2.JSON;
import com.bto.solar.work.common.BizLoginException;
import com.bto.solar.work.common.RedisService;
import com.bto.solar.work.constant.TokenConstants;
import com.bto.solar.work.utils.JwtUtils;
import com.bto.solar.work.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 拦截器
 * @author Administrator
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisService redisService;

    @Override
    public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
        try {
            if ("OPTIONS".equals(request.getMethod())) {
                log.info("OPTIONS请求，放行");
                return true;
            }
            //判断是否登录
            boolean isLogin = verify(request);
            if (!isLogin) {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.getWriter().write(toJson("token过期"));
                return false;
            }
            return true;
        } catch (Exception e) {
            throw new BizLoginException(401, "系统异常(token)，请重新登陆！");
        }
    }

    /**
     * 验证是否登录
     */
    public boolean verify(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        token = token.replace(TokenConstants.PREFIX, "");
        String redisKey = TokenConstants.TOKEN + JwtUtils.getUserId(token);
        String redisToken = redisService.getCacheObject(redisKey);
        boolean isVerify = StringUtils.isNotEmpty(redisToken) && redisToken.equals(token);
        //延期
        if (isVerify) {
            redisService.expire(redisKey, TokenConstants.AUTH_TOKEN_EXPIRE_MIN , TimeUnit.MINUTES);
        }
        return isVerify;
    }

    public String toJson (String msg) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 401);
        map.put("msg", msg);
        map.put("success", false);
        return JSON.toJSONString(map);
    }


}
